/*
   Copyright (c) [2021] IT.SOS
   wxsdk is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2.
   You may obtain a copy of Mulan PSL v2 at:
            http://license.coscl.org.cn/MulanPSL2
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
   See the Mulan PSL v2 for more details.
*/

package wxchat

import (
	"strings"

	"gitee.com/itsos/wxsdk/common/config"
)

type AuthorizeDTO struct {
	AccessToken  string `json:"access_token"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	Openid       string `json:"openid"`
	Scope        string `json:"scope"`
}

type UserInfoDTO struct {
	Openid     string   `json:"openid"`
	Nickname   string   `json:"nickname"`
	Sex        int      `json:"sex"`
	Province   string   `json:"province"`
	City       string   `json:"city"`
	Country    string   `json:"country"`
	Headimgurl string   `json:"headimgurl"`
	Privilege  []string `json:"privilege"`
	Unionid    string   `json:"unionid"`
}

// scope 静默授权与用户授权
const (
	ScopeSnsBase = "snsapi_base"
	ScopeSnsInfo = "snsapi_userinfo"
)

// Authorize 网页授权相关接口
type Authorize interface {
	// SnsApiBase 静默授权
	SnsApiBase(redirectUri, state string) (string, error)
	// SnsApiUserInfo 用户授权
	SnsApiUserInfo(redirectUri, state string) (string, error)
	// SnsAccessToken code换取access_token
	SnsAccessToken(code string) (AuthorizeDTO, error)
	// SnsAuthAccessToken 验证access_token
	SnsAuthAccessToken() error
	// SnsRefreshToken 刷新access_token
	SnsRefreshToken() (AuthorizeDTO, error)
	// SnsUserInfo 拉取用户信息
	SnsUserInfo() (UserInfoDTO, error)
}

type authorize struct{}

func (a authorize) SnsApiBase(redirectUri, state string) (string, error) {
	return strings.NewReplacer("{appid}", config.Cfg.GetWxAppId(),
		"{redirect_uri}", redirectUri,
		"{scope}", ScopeSnsBase,
		"{state}", state).Replace(getSnsCodeUrl), nil
}

func (a authorize) SnsApiUserInfo(redirectUri, state string) (string, error) {
	return strings.NewReplacer("{appid}", config.Cfg.GetWxAppId(),
		"{redirect_uri}", redirectUri,
		"{scope}", ScopeSnsInfo,
		"{state}", state).Replace(getSnsCodeUrl), nil
}

func (a authorize) SnsAccessToken(code string) (AuthorizeDTO, error) {
	strings.NewReplacer("{appid}", config.Cfg.GetWxAppId(),
		"{secret}", config.Cfg.GetWxAppSecret(),
		"{code}", code).Replace(getSnsAccessTokenUrl)
	panic("implement me")
}

func (a authorize) SnsAuthAccessToken() error {
	panic("implement me")
}

func (a authorize) SnsRefreshToken() (AuthorizeDTO, error) {
	panic("implement me")
}

func (a authorize) SnsUserInfo() (UserInfoDTO, error) {
	panic("implement me")
}

var _ Authorize = (*authorize)(nil)

func NewAuthorize() Authorize {
	return new(authorize)
}
